/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef HKS_TYPE_H
#define HKS_TYPE_H

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

enum HksKeyPurpose {
    HKS_KEY_PURPOSE_ENCRYPT = 1,                   /* Usable with RSA, EC, AES, and SM4 keys. */
    HKS_KEY_PURPOSE_DECRYPT = 2,                   /* Usable with RSA, EC, AES, and SM4 keys. */
};

enum HksKeyPadding {
    HKS_PADDING_NONE = 0,
};

enum HksCipherMode {
    HKS_MODE_GCM = 32,
};

enum HksKeySize {
    HKS_RSA_KEY_SIZE_4096 = 4096,
    HKS_AES_KEY_SIZE_256 = 256,
};

enum HksKeyAlg {
    HKS_ALG_AES = 20,
};

enum HksErrorCode {
    HKS_SUCCESS = 0,
    HKS_FAILURE = -1,
    HKS_ERROR_INVALID_ARGUMENT = -3,
};

enum HksTagType {
    HKS_TAG_TYPE_INVALID = 0 << 28,
    HKS_TAG_TYPE_INT = 1 << 28,
    HKS_TAG_TYPE_UINT = 2 << 28,
    HKS_TAG_TYPE_ULONG = 3 << 28,
    HKS_TAG_TYPE_BOOL = 4 << 28,
    HKS_TAG_TYPE_BYTES = 5 << 28,
};

#define HKS_ASSIGN_ENUM_VALUE(x, y) x = y,

#define HKS_ASSIGN_PARAM_ALG_ENUM \
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_INVALID, HKS_TAG_TYPE_INVALID | 0) \
    /* Base algrithom TAG: 1 - 200 */\
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_ALGORITHM, HKS_TAG_TYPE_UINT | 1) \
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_PURPOSE, HKS_TAG_TYPE_UINT | 2) \
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_KEY_SIZE, HKS_TAG_TYPE_UINT | 3) \
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_DIGEST, HKS_TAG_TYPE_UINT | 4) \
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_PADDING, HKS_TAG_TYPE_UINT | 5) \
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_BLOCK_MODE, HKS_TAG_TYPE_UINT | 6) \
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_KEY_TYPE, HKS_TAG_TYPE_UINT | 7) \
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_ASSOCIATED_DATA, HKS_TAG_TYPE_BYTES | 8) \
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_NONCE, HKS_TAG_TYPE_BYTES | 9) \
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_IV, HKS_TAG_TYPE_BYTES | 10) \
    /* Inner-use TAG: 10001 - 10999 */\
    HKS_ASSIGN_ENUM_VALUE(HKS_TAG_AE_TAG, HKS_TAG_TYPE_BYTES | 10009) \

/**
 * @brief hks Tag
 */
enum HksTag {
    /**
     * HUKS tags for alg enum
     */
    HKS_ASSIGN_PARAM_ALG_ENUM

    /**
     * HUKS tags for key file enum
     */
    HKS_ASSIGN_PARAM_FILE_ENUM
};

/**
 * @brief hks blob
 */
struct HksBlob {
    uint32_t size;
    uint8_t *data;
};

/**
 * @brief hks param
 */
struct HksParam {
    uint32_t tag;
    union {
        bool boolParam;
        int32_t int32Param;
        uint32_t uint32Param;
        uint64_t uint64Param;
        struct HksBlob blob;
    };
};

struct HksParamSet {
    uint32_t paramSetSize;
    uint32_t paramsCnt;
    struct HksParam params[];
};
#endif /* HKS_TYPE_H */